using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Services;
using XNAColor = Microsoft.Xna.Framework.Color;


namespace MainGame.Menu
{
  public delegate void MenuEvent();

  public enum MenuDepths
  {
    Background,
    GameLayer,
    Overlay,
    BackMenu,
    MiddleMenu,
    FrontMenu,
    ForeGround,
    Decoration,
    numMenus
  }


  /// <summary>
  /// This is a game component that implements IUpdateable.
  /// </summary>
  public class BaseMenu : Microsoft.Xna.Framework.DrawableGameComponent
  {
    public struct ClickableButton
    {
      public Button b;
      public Action on_click;
    }

    public List<ClickableButton> buttons { get; private set; }
    public Texture2D background { get; set; }
    public Rectangle bounds;
    SpriteBatch spriteBatch;
    int ColorCounter = 5;
    Color SavedColor, touchedColor;
    public MenuDepths menuDepth;
    Matrix screen_transform, smaller_screen_transform;
    RenderTarget2D smaller_render_target;

    public BaseMenu(Game game, MenuDepths depth)
      : base(game)
    {
      spriteBatch = Game.GetContext().SpriteBatch;
      buttons = new List<ClickableButton>();
      this.menuDepth = depth;
      this.DrawOrder = (int)depth;
    }

    public override void Initialize()
    {
      var input_service = Game.Services.GetService(typeof(IInputManager)) as IInputManager;
      input_service.OnTap += new InputManager.Tap(input_service_OnTap);

      base.Initialize();
    }

    protected override void Dispose(bool disposing)
    {
      base.Dispose(disposing);
    }

    protected override void LoadContent()
    {
      smaller_render_target = new RenderTarget2D(GraphicsDevice, GraphicsDevice.Viewport.Width / 3, GraphicsDevice.Viewport.Height / 3);
      smaller_screen_transform = Matrix.CreateScale((float)smaller_render_target.Width / GraphicsDevice.Viewport.Width,
          (float)smaller_render_target.Height / GraphicsDevice.Viewport.Height, 1.0f);

      base.LoadContent();
    }

    protected void AddButton(Button b, Action on_click)
    {
      buttons.Add(new ClickableButton() { b = b, on_click = on_click });
    }

    private void input_service_OnTap(Vector2 tapPosition)
    {
      if (this.Enabled == false) return;

      var screenTransform = Game.GetContext().ScreenTransform;
      foreach (var cb in buttons)
      {
        if (cb.b.IsInBounds(tapPosition.ToPoint(screenTransform)))
          cb.on_click();
      }
    }

    public override void Draw(GameTime gameTime)
    {
      spriteBatch.Begin();
      if (background != null)
        spriteBatch.Draw(background, bounds, null, Color.White, 0, Vector2.Zero, SpriteEffects.None, (float)DrawOrder / (float)MenuDepths.numMenus);
      float buttonsDepth = ((float)DrawOrder / (float)MenuDepths.numMenus) + 0.01f;

      foreach (Button b in (from cb in buttons select cb.b))
      {
        spriteBatch.Draw(b.texture, b.bounds, null, b.color, 0, Vector2.Zero, SpriteEffects.None, buttonsDepth);
        spriteBatch.DrawString(b.spriteFont, b.message, new Vector2((float)b.bounds.Center.X, (float)b.bounds.Center.Y), b.textColor, 0, b.spriteFont.MeasureString(b.message) / 2, b.scale, SpriteEffects.None, buttonsDepth);

        //Controlla se il pulsante deve avere l'effetto "premuto"
        if (b.touched)
        {
          // Salva il colore originale
          if (b.color != touchedColor)
            SavedColor = b.color;
          //Controlla se il pulsante ha un colore specifico per l'effetto "premuto"
          if (b.TouchColor != new Color(0, 0, 0, 0))
            touchedColor = b.TouchColor;
          else
            touchedColor = Color.Lerp(Color.Black, SavedColor, 0.5f);
          //touchedColor = Color.Turquoise;

          //touchedColor.A = 255;

          //Assegna la Lerp dei due colori
          b.color = touchedColor;

          //Tempo di durata effetto
          ColorCounter--;
          if (ColorCounter < 0)
          {
            b.color = SavedColor;
            ColorCounter = 5;
            b.touched = false;

          }
        }
      }

      spriteBatch.End();

      base.Draw(gameTime);
    }
  }
}
